/*******************************************************************************
 * Copyright (c) 2010, 2017 西安秦晔信息科技有限公司
 * Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *******************************************************************************/
package com.qinyeit.webapp.controller.management.system;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.qinyeit.serviceapp.entity.system.ManagementAccount;
import com.qinyeit.serviceapp.service.system.ManagementAccountService;
import com.qinyeit.webapp.controller.management.BaseManagementController;
import com.qinyeit.webapp.utils.CurrentAccountUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.http.ResponseStatusCode;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.security.exception.BlankPasswordException;
import com.qinyetech.springstage.core.security.exception.JcaptchaCodeException;
import com.qinyetech.springstage.core.security.util.Coder;
import com.qinyetech.springstage.core.web.dto.ResponseResult;
import com.qinyetech.springstage.core.web.jcaptcha.JCaptcha;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.qinyeit.webapp.utils.CurrentAccountUtils.*;
import static com.qinyeit.webapp.utils.CurrentAccountUtils.getAuthenticatedAccountName;

/** 
 * ClassName: AuthenticateController <br/> 
 * Function: 登录，退出 <br/> 
 * date: 2015年8月22日 下午4:58:30 <br/> 
 * 
 * @author wuqing 
 * @version  
 * @since JDK 1.8
 */
@RestController
public class AuthenticateController extends BaseManagementController {

    @Autowired
    private ManagementAccountService managementAccountService;

    @PostMapping("/management/signin")
	public ResponseResult signin(HttpServletRequest req, Model model){
	    //认证成功
	    if(SecurityUtils.getSubject().isAuthenticated()){
	        log.info("------------------认证成功");
            try {
                QyMap map=QyMap.NEW()
                        .setv("accountName",Coder.encryptStrToBASE64(getAuthenticatedAccountName()))
                        .setv("securityKey",getAuthenticatedAccountSecurityKey())
                        .setv("accessToken",getSessionId())
                        .setv("accountRealName",getAuthenticatedAccountRealName())
                        .setv("headUrl",getHeadPicUrl())
                        .setv("lastLoginDate",getLastLoginDate()==null?DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"):DateUtils.format(getLastLoginDate(),"yyyy-MM-dd HH:mm:ss"));

                log.info("---------------------01");

//                根据账号获取角色字符串
//                List<Map<String,Object>> roleCodes= managementAccountService.findByAccount(getAuthenticatedAccountName());
//                        .getRolesByAccount(getAuthenticatedAccountID(),getAuthenticatedMerchantGroupID());
//                log.info("根据账号获取角色字符串 : {}",roleCodes);
                ManagementAccount account = managementAccountService.findById(getAuthenticatedAccountID());
                log.info("---------------------02");
//                if(getAuthenticatedIsAdmin()){
//
//                }else {
//                    ManagementAccount account=managementAccountService.findByAccount(getAuthenticatedAccountName());
//                }
//                ManagementAccount account=managementAccountService.findByAccount(getAuthenticatedAccountName());
                map.setv("admin",account.isAdmin());
                log.info("---------------------03");
                map.setAll(getCurrentAccountAuthInfo(account));
                log.info("---------------------04");
                return ok("登录成功!",map);

            } catch (Exception e) {
                log.info("---------------------05");
                log.info("e:{}",e);
                return fail("未知错误");
            }

        }
        String exceptionClassName = (String)req.getAttribute("shiroLoginFailure");
        String error = null;
        if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
            error = "用户名/密码错误";
        } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
            error = "用户名/密码错误";
        } else if(ExcessiveAttemptsException.class.getName().equals(exceptionClassName)){
            error="登录次数过多";
        }else if(BlankPasswordException.class.getName().equals(exceptionClassName)){
            error="密码为空";
        }else if(LockedAccountException.class.getName().equals(exceptionClassName)){
            error="账户被锁定";
        }else if(JcaptchaCodeException.class.getName().equals(exceptionClassName)){
            error="验证码错误";
        }else if(exceptionClassName != null) {
            error = "其他错误：" + exceptionClassName;
        }
        ResponseResult response=fail(error);
        return response;
    }

	@GetMapping("/management/logout")
	public  ResponseResult<String> logout(){

	    SecurityUtils.getSubject().logout();

        return ok("退出成功");
	}

    @GetMapping("/management/jcaptcha")
    public  ResponseResult<String> jcaptcha(HttpServletRequest request){
        String id = request.getSession().getId();
        BufferedImage bi = JCaptcha.captchaService.getImageChallengeForID(id);
        String imgPrefix="data:image/jpeg;base64,";
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        log.info("jcaptcha session id :::>>>>>>>>>>>>>:{}",id);
        try {
            ImageIO.write(bi, "jpg", bos);
            bos.flush();
           String imageBase64= Coder.encryptBASE64(bos.toByteArray());
           return ok("",imgPrefix+imageBase64);
        } catch (Exception e) {
            try {
                bos.close();
            } catch (IOException e1) {
            }
        }
        return ok("产生验证码出错","");
    }

    //获取登录账号所有权限和角色
    @GetMapping("/management/authorizationInfo")
    public ResponseResult<QyMap> authorizationInfo(){
        //获取当前账号
        ManagementAccount account=managementAccountService.findByAccount(getAuthenticatedAccountName());
         return  ok("",getCurrentAccountAuthInfo(account));
    }

    private QyMap getCurrentAccountAuthInfo(ManagementAccount account){
//        Set<String> permissions = managementAccountService.findPermissionCodeSet(account.getAccount());
        List<Map<String,Object>> permissions = managementAccountService.getPermissionCodeSet(account.getId());
        log.info("-----------------aa----001");
        QyMap root=QyMap.NEW();
        if(CollectionUtils.isEmpty(account.getRoles())){
            log.info("-----------------aa----002");
            root.setv("roles",Collections.EMPTY_MAP);
        }else {
            log.info("-----------------aa----003");
            Map<String, String> roleMap = account.getRoles().stream().collect(Collectors.toMap(p1 -> p1.getCode(), p2 -> p2.getName()));
            root.setv("roles", roleMap);
        }
        if(CollectionUtils.isEmpty(permissions)){
            log.info("-----------------aa----004");
            root.setv("permissions",Collections.EMPTY_MAP);
        }else {
            log.info("-----------------aa----005");
//            Map<String, String> permissionMap = account.getPermissions().stream().collect(Collectors.toMap(p1 -> p1.getCode(), p2 -> p2.getName()));
            Map<String, String> permissionMap= Maps.newHashMap();
            permissionMap = permissions.stream().collect(Collectors.toMap(p1->p1.get("code").toString(),p2 -> p2.get("name").toString()));
            root.setv("permissions", permissionMap);
        }
        log.info("-----------------aa----006");
        return root;
    }

}
